PROJECTENGRAM

04 - POWAH UNLIMITED POWAH

Tags: #◇Computer Science #◇CSALGCM #◇Algorithms and Complexity #◇HackerRank #◇Priestess Arcana #◇Modular Exponentiation #◇Fast Power


POWAH! UNLIMITED POWAH!

◇Problem Description

Emperor Palpatine unleashes lightning with an initial power of XX. Every millisecond, the power increases by a factor of XX. Given his initial energy XX and the number of milliseconds NN he has been shooting lightning, the task is to compute his final lightning power modulo a large integer MM.

Input Format:
Input consists of a single test case containing a line with two integers XX and NN separated by a space indicating the energy and the time elapsed in milliseconds.

Output Format:
Output consists of one line containing Palpatine's power XNX^N after NN milliseconds modulo MM.

Constraints:

Sample:

InputOutput
2 416
10 410000

◇Approach & Intuition

** Abstract the problem**
Emperor Palpatine fires lightning that starts at power 1 and multiplies by E every millisecond. After T milliseconds, the power is E^T. Output E^T mod 10^7.

** Dumb sol?**
Multiply by E repeatedly, T times: result = 1; for t times: result *= E;
O(T) — T can be up to 10¹², which means 1 trillion multiplications → TLE (would take hours).

** Smart sol?**
Read the exponent in binary. Only ~40 bits are needed. Square-and-multiply: O(log T) steps.
O(log T) ≈ 40 steps — runs instantly.


◇The Two Bugs Fixed

Bug 1: Wrong Modulus

『』
TEXT
Problem says: output P modulo 10^7  (= 10,000,000)
Old code used:               10^9+7 (= 1,000,000,007)  ← completely different!

Both sample answers (16 and 10000) are small enough to pass either modulus,
so the bug is invisible on samples but wrong for large exponents.

Bug 2: Variable Name exp Shadows C Stdlib

『』
C
// C's standard library defines:
double exp(double x);   // Euler's e^x

// Old code used:
long long exp = t;      // Shadows the stdlib function!
// Causes undefined behavior on some compilers → wrong results

// Fix: rename to exponent
long long exponent = t;

◇Fast Exponentiation: Exponentiation by Squaring

Core Idea: Express the exponent in binary. Each '1' bit contributes a power of 2. Keep squaring the base to move through powers of 2.

『』
TEXT
Computing 2^13:
  13 in binary = 1 1 0 1
                 ^ ^ ^ ^
                 8 4 2 1   ← place values

  2^13 = 2^8 × 2^4 × 2^1   (skip 2^2 because bit-1 is 0)
       = 256 × 16 × 2 = 8192

Reading bits RIGHT to LEFT (low bit first):
  bit 0 = 1: result *= base(=2¹)   result=2,   base squares → 4
  bit 1 = 0: skip                  result=2,   base squares → 16
  bit 2 = 1: result *= base(=2⁴)   result=32,  base squares → 256
  bit 3 = 1: result *= base(=2⁸)   result=8192. Done!
  Total: 4 steps instead of 13!

For T = 10¹²: about 40 binary digits → 40 steps instead of 10¹².


◇Modular Arithmetic: Why % At Every Step

『』
TEXT
Without mod: numbers explode immediately.
  2^63 ~ 9.2 × 10^18  ← barely fits in int64
  2^64 = OVERFLOW → garbage → wrong answer

With mod applied at each step:
  Mathematical law: (a × b) mod m = ((a mod m) × (b mod m)) mod m
  This means applying mod per step = same result as applying once at end.

  Max intermediate: (10^7 - 1)² = ~10^14 << int64_max (9.2×10^18)
  So no overflow ever occurs! 

◇Algorithm Flowchart


◇Full Trace: E=2, T=13

exponentbinarylowest bit?resultbase after squaring
13110111 × 2 = 22² = 4
6011002 (no change)4² = 16
3001112 × 16 = 3216² = 256
10001132 × 256 = 8192256² = 65536
00000—Loop ends—

Output: 8192 = 2¹³


◇Code: Every Line Explained

『』
C
int main() {
    long long e, t;
    scanf("%lld%lld", &e, &t);

    long long base = e % 10000000;
    // Reduce base first! e can be up to 10^12.
    // Squaring unreduced: (10^12)^2 = 10^24 → immediate overflow.
    // After mod: base < 10^7, so base^2 < 10^14 → safe in int64.

    long long exponent = t;
    // Named 'exponent', NOT 'exp' — 'exp' is C stdlib (Euler's e^x).
    // Using 'exp' as a variable name causes shadowing → undefined behavior.

    long long result = 1;
    // Start at 1 (multiplicative identity).
    // We accumulate: result = E^(bits we've processed so far).

    while (exponent > 0) {
        if (exponent & 1) {
            // Bitwise AND with 1: true if lowest bit is 1.
            // This bit's contribution: multiply result by current base.
            result = (result * base) % 10000000;
        }

        base = (base * base) % 10000000;
        // Square the base: base goes 2→4→16→256→65536→...
        // Each squaring doubles the exponent the base represents.

        exponent >>= 1;
        // Bit shift right by 1 = integer divide by 2.
        // Discards the bit we just processed, exposing the next bit.
    }

    printf("%lld\n", result);
}

◇Complexity Analysis

Complexity
TimeO(log t)
SpaceO(1)

◇Original Stub (HackerRank Template)

『』
CPP
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

ll modpow(ll base, ll exp, ll mod) {
    // Write your code here
}

int main() {
    ll X, N, M;
    cin >> X >> N >> M;
    
    // Write your code here
    
    return 0;
}

◇Full Solution

『』
CPP
#include <stdio.h>

int main() {
  	long long e, t;
	scanf("%lld%lld",&e,&t);
	// compute answer
    // Fast modular exponentiation: e^t mod 10^7 (= 10000000)
    long long base = e % 10000000;
    long long exponent = t;
    long long result = 1;
    while (exponent > 0) {
        if (exponent & 1) result = (result * base) % 10000000;
        base = (base * base) % 10000000;
        exponent >>= 1;
    }
    printf("%lld\n", result);
}

◇References & Navigation

04 - POWAH UNLIMITED POWAH | PROJECT ENGRAM